{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "bdcd26a5-3dec-440b-a0aa-c3027aa55601",
   "metadata": {},
   "source": [
    "# Set up the project"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "e48c84b0-7c1a-4374-a49f-91b3bf773470",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-03-12T02:27:23.341538Z",
     "start_time": "2024-03-12T02:27:21.640844Z"
    },
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "import os\n",
    "\n",
    "from label_studio_sdk import LabelStudio\n",
    "\n",
    "LABEL_STUDIO_URL = os.environ.get('LABEL_STUDIO_URL')\n",
    "API_KEY = os.environ.get('LABEL_STUDIO_API_KEY')\n",
    "\n",
    "# for storages\n",
    "AWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY_ID')\n",
    "AWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_ACCESS_KEY')\n",
    "\n",
    "ls = LabelStudio(base_url=LABEL_STUDIO_URL, api_key=API_KEY)\n",
    "\n",
    "# Start new project \n",
    "project = ls.projects.create(\n",
    "    title='Storage Test Project',\n",
    "    label_config='''\n",
    "    <View>\n",
    "      <Image name=\"image\" value=\"$image\" zoom=\"true\"/>\n",
    "      <PolygonLabels name=\"label\" toName=\"image\">\n",
    "        <Label value=\"Airplane\" background=\"red\"/>\n",
    "      </PolygonLabels>\n",
    "    </View>\n",
    "    '''\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "690d7251eb454b75",
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "source": [
    "## Add a source (import) storage to the project"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "e50714816b61fc89",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-03-12T02:00:05.659227Z",
     "start_time": "2024-03-12T02:00:05.002251Z"
    },
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "import_storage = ls.import_storage.s3.create(\n",
    "    project=project.id,\n",
    "    title=\"my storage\", \n",
    "    bucket=\"htx-dev\",\n",
    "    prefix=\"dataset/training_set/dogs\",\n",
    "    aws_access_key_id=AWS_ACCESS_KEY_ID,\n",
    "    aws_secret_access_key=AWS_SECRET_ACCESS_KEY,\n",
    "    use_blob_urls=True,  # \"Treat every bucket object as a source file\", more info: https://labelstud.io/guide/storage#Treat-every-bucket-object-as-a-source-file\n",
    "    regex_filter=\".*jpg\"\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "958e0a55-5ac5-4141-a311-72d7a4cabf8e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "S3ImportStorage(aws_access_key_id=None, aws_secret_access_key=None, aws_session_token=None, aws_sse_kms_key_id=None, bucket='htx-dev', created_at=datetime.datetime(2025, 9, 30, 15, 7, 4, 603292, tzinfo=datetime.timezone.utc), description=None, id=5216, last_sync=None, last_sync_count=None, last_sync_job=None, meta={}, prefix='dataset/training_set/dogs', presign=True, presign_ttl=1, project=459758, recursive_scan=False, regex_filter='.*jpg', region_name=None, s3endpoint=None, status='initialized', synchronizable=True, title='my storage', traceback=None, type='s3', use_blob_urls=True)"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import_storage"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "56495cc8c60b839d",
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "source": [
    "## Sync import storage to get tasks from the storage "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "b21dfcfa1cc06d8d",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-03-12T02:00:06.682288Z",
     "start_time": "2024-03-12T02:00:05.674913Z"
    },
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "sync_result = ls.import_storage.s3.sync(import_storage.id)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "fb7aea35f6d1c361",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-03-12T02:00:06.688760Z",
     "start_time": "2024-03-12T02:00:06.683698Z"
    },
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "S3ImportStorage(aws_access_key_id=None, aws_secret_access_key=None, aws_session_token=None, aws_sse_kms_key_id=None, bucket='htx-dev', created_at=datetime.datetime(2025, 9, 29, 21, 20, 56, 91931, tzinfo=datetime.timezone.utc), description=None, id=5180, last_sync=None, last_sync_count=None, last_sync_job='dfac54a3-db91-4e4c-9a45-80b32b855c81', meta={'attempts': 1, 'time_queued': '2025-09-29 21:21:09.438564+00:00'}, prefix='dataset/training_set/dogs', presign=True, presign_ttl=1, project=456308, recursive_scan=False, regex_filter='.*jpg', region_name=None, s3endpoint=None, status='queued', synchronizable=True, title='my storage', traceback=None, type='s3', use_blob_urls=True)"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sync_result"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e8909bcce0ffe275",
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "source": [
    "## Get status of synchronization for the storage\n",
    "\n",
    "And wait until sync is completed. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "26a9cc0311e30b77",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-03-12T02:00:57.268095Z",
     "start_time": "2024-03-12T02:00:06.691848Z"
    },
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Import storage 5180 is synced!\n"
     ]
    }
   ],
   "source": [
    "import time\n",
    "\n",
    "while import_storage.status != 'completed':\n",
    "    time.sleep(3.0)  # wait for 3 seconds    \n",
    "    \n",
    "    import_storage = ls.import_storage.s3.get(import_storage.id)\n",
    "    print(import_storage.id, import_storage.title, import_storage.status)\n",
    "\n",
    "print(f'Import storage {import_storage.id} is synced!')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8e7b78c7908bba75",
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "source": [
    "## Add a target (export) storage to the project"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "2ee23267e0319077",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-03-12T02:06:31.102399Z",
     "start_time": "2024-03-12T02:06:30.528712Z"
    },
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "export_storage = ls.export_storage.s3.create(\n",
    "    project=project.id,\n",
    "    title=\"my export storage\", \n",
    "    bucket=\"htx-dev\",\n",
    "    prefix=\"test_out\",\n",
    "    aws_access_key_id=AWS_ACCESS_KEY_ID,\n",
    "    aws_secret_access_key=AWS_SECRET_ACCESS_KEY,\n",
    "    can_delete_objects=False  # if you delete annotations in Label Studio, the corresponding objects in the storage will not be deleted\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "1f4ae7ac1e715d06",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-03-12T02:06:31.837883Z",
     "start_time": "2024-03-12T02:06:31.831130Z"
    },
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "S3ExportStorage(aws_access_key_id=None, aws_secret_access_key=None, aws_session_token=None, aws_sse_kms_key_id=None, bucket='htx-dev', can_delete_objects=False, created_at=datetime.datetime(2025, 9, 30, 15, 7, 28, 766966, tzinfo=datetime.timezone.utc), description=None, id=3405, last_sync=None, last_sync_count=None, last_sync_job='7273680f-109f-4585-a7d4-9f6000a68712', meta={'attempts': 1, 'time_queued': '2025-09-30 15:07:28.793453+00:00'}, prefix='test_out', project=459758, regex_filter=None, region_name=None, s3endpoint=None, status='queued', synchronizable=True, title='my export storage', traceback=None, type='s3', use_blob_urls=False)"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "export_storage"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1b6ea2541227029d",
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "source": [
    "## Sync target storage to save annotations to the storage\n",
    "\n",
    "Target storages sync automatically, so we don't need to call any methods to sync them. However, if you need to re-sync the storage from the scratch, you can call `sync` method."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "7e946b1b0811e327",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-03-12T02:06:35.057464Z",
     "start_time": "2024-03-12T02:06:34.486739Z"
    },
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "S3ExportStorage(aws_access_key_id=None, aws_secret_access_key=None, aws_session_token=None, aws_sse_kms_key_id=None, bucket='htx-dev', can_delete_objects=False, created_at=datetime.datetime(2025, 9, 30, 15, 7, 28, 766966, tzinfo=datetime.timezone.utc), description=None, id=3405, last_sync=None, last_sync_count=None, last_sync_job='7273680f-109f-4585-a7d4-9f6000a68712', meta={'attempts': 1, 'time_queued': '2025-09-30 15:07:28.793453+00:00'}, prefix='test_out', project=459758, regex_filter=None, region_name=None, s3endpoint=None, status='queued', synchronizable=True, title='my export storage', traceback=None, type='s3', use_blob_urls=False)"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sync_result = ls.export_storage.s3.sync(export_storage.id)\n",
    "sync_result"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
